/*
 *  AvTypes.cpp
 *  libavid
 *
 *  Created by Peter on 23.02.12.
 *  Copyright 2012 __MyCompanyName__. All rights reserved.
 *
 */
#include "AvTypes.h"
#include "AStream.h"

#include <iomanip>

void AvRect::readFromStream( AStream& str )
{
	Int16 version;
	str.readPod( version );
	
	TR_ASSERT( version == 1 );
	
	str.readPod( _values[ 0 ] );
	str.readPod( _values[ 1 ] );
	str.readPod( _values[ 2 ] );
	str.readPod( _values[ 3 ] );
}

void AvRect::dump( std::ostream& str ) const
{
	str << "AvRect {" << std::endl;
	str << "\t" << _values[ 0 ] << "," << std::endl;
	str << "\t" << _values[ 1 ] << "," << std::endl;
	str << "\t" << _values[ 2 ] << "," << std::endl;
	str << "\t" << _values[ 3 ] << std::endl;
	str << "}" << std::endl;
}

void AvRgbColor::readFromStream( AStream& str )
{
	Int16 version;
	str.readPod( version );
	
	TR_ASSERT( version == 1 );
	
	str.readPod( _values[ 0 ] );
	str.readPod( _values[ 1 ] );
	str.readPod( _values[ 2 ] );	
}

void AvRgbColor::dump( std::ostream& str ) const
{
	str << "AvRgbColor {" << std::endl;
	str << "\t" << _values[ 0 ] << "," << std::endl;
	str << "\t" << _values[ 1 ] << "," << std::endl;
	str << "\t" << _values[ 2 ] << std::endl;
	str << "}" << std::endl;
}

std::ostream& operator<<( std::ostream& str, const AvRgbColor& color )
{
	color.dump( str );
	return str;
}

void Rational::readFromStream( AStream& str )
{
	str.readPod( numerator );
	str.readPod( denominator );
}

void Rational::writeToStream( AStream& str ) const
{
	str.writePod( numerator );
	str.writePod( denominator );
}

void Rational::dump( std::ostream& str ) const
{
	str << "Rational {" << std::endl;
	str << "\tnumerator: " << numerator << std::endl;
	str << "\tdenominator: " << denominator << std::endl;
	str << "}" << std::endl;
}

std::ostream& operator<<( std::ostream& str, const Rational& r )
{
	r.dump( str );
	return str;
}

void acfUID::readFromStream( AStream& str )
{
	str.readPod( Data1 );
	str.readPod( Data2 );
	str.readPod( Data3 );
	str.readBuffer( Data4, 8 );
}

void readAcfUidFromObjDocStream( AStream& str, acfUID& uid )
{
	UInt8 tagMark;
	
	str.readPod( tagMark );
	TR_CHECK( tagMark == 72 );
	str.readPod( uid.Data1 );
	
	str.readPod( tagMark );
	TR_CHECK( tagMark == 70 );
	str.readPod( uid.Data2 );
	
	str.readPod( tagMark );
	TR_CHECK( tagMark == 70 );
	str.readPod( uid.Data3 );
	
	str.readPod( tagMark );
	TR_CHECK( tagMark == 65 );
	Int32 data4len;
	str.readPod( data4len );
	TR_ASSERT( data4len == 8 );
	
	str.readBuffer( uid.Data4, 8 );
}

#define TRACE_FIELD( x ) "\t" #x ": " << x << std::endl
#define TRACE_CHAR_FIELD( x ) "\t" #x ": " << static_cast< int >( x ) << std::endl

std::ostream& operator<<( std::ostream& str, const acfUID& uid )
{
	str << "acfUID { ";
	
	std::ios::fmtflags flags = str.flags();
	
	str << std::hex;
	str << uid.Data1 << "-";
	str << uid.Data2 << "-";
	str << uid.Data3 << "-";

	for( int i = 0; i < 8; ++i )
		str << static_cast< int >( uid.Data4[ i ] );
	
	str << " }";
	
	str.flags( flags );
	
	return str;
}

#define TRACE_MID_FIELD( x ) "\t" #x ": " << mid.x << std::endl
#define TRACE_MID_CHAR_FIELD( x ) "\t" #x ": " << static_cast< int >( mid.x ) << std::endl

std::ostream& operator<<( std::ostream& str, const aafMCMobID_t& mid )
{
	str << "aafMCMobID_t {" << std::endl;
	
	str << "\tSMPTELabel:";
	for( int i = 0; i < 12; ++i )
		str << " " << static_cast< int >( mid.SMPTELabel[ i ] );
	str << std::endl;	
	
	str << TRACE_MID_CHAR_FIELD( length );
	str << TRACE_MID_CHAR_FIELD( instanceHigh );
	str << TRACE_MID_CHAR_FIELD( instanceMid );
	str << TRACE_MID_CHAR_FIELD( instanceLow );
	str << TRACE_MID_FIELD( material );
	
	str << "}";
	
	return str;
}

void readMobIdFromAObjDocStream( AStream& str, aafMCMobID_t& mid )
{
	UInt8 tagMark, version;
	
	// SMPTE Label Len and Value
	str.readPod( tagMark );
	str.readPod( version );
	TR_ASSERT( tagMark == 0x01 );
	TR_ASSERT( version = 0x02 ); // Minor Version
	str.readPod( tagMark );
	TR_ASSERT( tagMark == 65 );
	
	Int32 smpteLabelLen;
	str.readPod( smpteLabelLen );
	TR_ASSERT( smpteLabelLen == 12 ); // Always 12

	str.readBuffer( mid.SMPTELabel, 12 );
	
	str.readPod( tagMark );
	TR_ASSERT( tagMark == 68 );
	str.readPod( mid.length );
	
	str.readPod( tagMark );
	TR_ASSERT( tagMark == 68 );
	str.readPod( mid.instanceHigh );
	
	str.readPod( tagMark );
	TR_ASSERT( tagMark == 68 );
	str.readPod( mid.instanceMid );
	
	str.readPod( tagMark );
	TR_ASSERT( tagMark == 68 );
	str.readPod( mid.instanceLow );
	
	readAcfUidFromObjDocStream( str, mid.material );
}

